package Store;

import Auxiliary.Sequence_String;
import Auxiliary.Sequence_Type;
import DataView.CDElementInfo;
import DataView.ClassDiagramInfo;
import DataView.ClassInfo;
import DataView.EnumerationInfo;
import DataView.Environment;
import DataView.Sequence_Error;
import Visualization.ClassDiagramVis;

public class ClassDiagram extends Element 
{
	private ClassDiagramInfo info = new ClassDiagramInfo();
	
	public void mkElement(ClassDiagramInfo aElIN) 
	{
		super.mkElement(aElIN);
		info=aElIN;
	}
	
	public Sequence_Error check() 
	{
		Sequence_Error lista = new Sequence_Error();
		for (Class c : info.getClassi())
		{
			int i =0;
			for (Class s : info.getClassi())
				if(c.getName().equals(s.getName()))
					i++;				

			if (i>1){
				lista.add("There are Two or more Classes with the name "+c.getName());
				break;
			}
		}
		for (Class c : info.getClassi())
		{
			for ( Attribute x : c.getInfo().list_Attribute)
			{
				int i=0;
				for (Attribute y : c.getInfo().list_Attribute)
					if(x.getName().equals(y.getName()))
						i++;
				if(i>1){
					lista.add("In "+c.getName()+"  there are  Two or more attributes with name "+x.getName());
					break;
				}
			}
		}
		for (Class c : info.getClassi())
		{
			for(Operation o : c.getInfo().list_Operation)
			{
				int i=0;
				for (Operation u : c.getInfo().list_Operation)
					if(o.getName().equals(u.getName()))
							i++;
				if(i>1){
					lista.add("In "+c.getName()+" there are Two or more operations with name "+o.getName());
					break;
				}
			}
		}
		//******************************************************************
		
		for (Enumeration e : info.getEnums())
		{
			int i =0;
			for (Enumeration n: info.getEnums())
				if(e.getName().equals(n.getName()))
					i++;				

			if (i>1){
				lista.add("There are  Two or more Enumeration Types with the name "+e.getName());
				break;
			}
		}
		for (Enumeration e: info.getEnums())
		{
			for ( String x : e.getInfo().getLiterals().getAll())
			{
				int i=0;
				for (String y : e.getInfo().getLiterals().getAll())
					if(x.equals(y))
						i++;
				if(i>1){
					lista.add("In "+e.getName()+"  there are Two or more Literals with name "+x);
					break;	
				}
			}
		}
		//******************************************************************
		return lista;
	}

	@SuppressWarnings("static-access")
	public Sequence_Type types() 
	{
		Sequence_Type tipi = new Sequence_Type();
		
		//Classi
		for(int i=0; i<info.getClassi().size(); i++)
			tipi.add(new Type().asType(info.getClassi().get(i)));
		//Enum
		for(int i=0; i<info.getEnums().size(); i++)
			tipi.add(new Type().asType(info.getEnums().get(i)));
		
		//Predefined 
		tipi.add(new Type().integer());
		tipi.add(new Type().boolean_());
		tipi.add(new Type().string());
		tipi.add(new Type().real());
		
		return tipi; 
	}

	public Environment env() 
	{
		throw new UnsupportedOperationException();
	}

	public void addCDElement(CDElement newElem) 
	{
		if (newElem.getClass()==Class.class)
		{
			((Class)newElem).getInfo();
			info.getClassi().add((Class)newElem);
		}
		else if (newElem.getClass()==Enumeration.class)
		{
			((Enumeration)newElem).getInfo();
			info.getEnums().add((Enumeration)newElem);
		}
		else System.out.println("Aggiungo nuovo elemento: errore\n");
	}

	public void deleteCDElement(CDElement elem) 
	{
		if (elem.getClass()==Class.class)
		{
			System.out.println("elimino la classe "+elem.getName()+"\n");
			info.getClassi().removeElement((Class)elem);
		}
		else if (elem.getClass()==Enumeration.class)
		{
			System.out.println("elimino l'enumeration "+elem.getName()+"\n");
			info.getEnums().removeElement((Enumeration)elem);
		}
		else System.out.println("Aggiungo nuovo elemento: errore\n");
	}

	public void updCDElement(CDElement elem, CDElementInfo elemInfo) 
	{
		if (elem.getClass()==Class.class && elemInfo.getClass()==ClassInfo.class)
			info.getClassi().get(info.getClassi().indexOf(elem)).mkElement((ClassInfo)elemInfo);
		else if (elem.getClass()==Enumeration.class && elemInfo.getClass()==EnumerationInfo.class)
			info.getEnums().get(info.getEnums().indexOf(elem)).mkElement((EnumerationInfo)elemInfo);
	}

	public void setContextClass(Class aClass) 
	{
		info.setContext(aClass);
	}
	
	public ClassDiagramVis vis()
	{
		Sequence_String classi = new Sequence_String();
		Sequence_String enums = new Sequence_String();
		int max=0;
		String s;
		if(info.getClassi()!=null) max= info.getClassi().size();
		for (int i=0 ; i<max ; i++)
		{
			s=info.getClassi().get(i).getName();
			if(info.getClassi().get(i).equals(info.getContext()))
				s=s+" -Context Class- ";
			else s=s+" :";
			for (Attribute str: info.getClassi().get(i).getInfo().list_Attribute)
				s=s+" \n"+str.getDescription();
			for (Operation opt: info.getClassi().get(i).getInfo().list_Operation)
				s=s+" \n"+opt.getDescription();
			classi.UNordered_add(s);
		}
		max=0;
		if(info.getEnums()!=null) max= info.getEnums().size();
		for (int i=0 ; i<max ; i++)
		{	s=info.getEnums().get(i).getName()+" :";
			for (String lit : info.getEnums().get(i).getInfo().getLiterals().getAll())
				s=s+" \n    "+lit;
			enums.UNordered_add(s);
		}
		ClassDiagramVis vista = new ClassDiagramVis(classi,enums);
		return vista;
	}
	
	
	
	public CDElement trova(String s)
	{
		CDElement trovato=null;
		int max=0;
		if(info.getClassi()!=null) max= info.getClassi().size();
		for (int i=0 ; i<max ; i++)
			if(info.getClassi().get(i).getName()==s)
				trovato=info.getClassi().get(i);
		max=0;
		if(info.getEnums()!=null) max= info.getEnums().size();
		for (int i=0 ; i<max ; i++)
			if(info.getEnums().get(i).getName()==s)
				trovato=info.getEnums().get(i);
		
		return trovato;
	}
	
	public ClassDiagramInfo getInfo()
	{
		return info;
	}

	public Class context()
	{
		return info.getContext();
	}

	public ClassDiagram clone() 
	{
		ClassDiagram clone = new ClassDiagram();
		clone.mkElement(info.clone());
		return clone;
	}
}